import os
import sys
import logging

sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), os.path.pardir))

from command_parser.ar_parse.ar_command_parser import ARParser
from utils.common_utils import *
from configure.compiler_configure import *
from base.context import Context
from utils.db_object_pool import DBObjectPool
from configure.config_logging import capture_log_init

class ARHandler(object):
    def __init__(self, command=[]):
        self.command = command
        self.env = {}
        self.cwd = ""
        self.context = Context()
        self.capture_db_handler = None
        self.cache_db_handler = None
    
    def init_env(self):
        self.cwd = os.getcwd()
        self.env = dict(os.environ)
        remove_envs_by_keys(env=self.env, remove_list=["LD_PRELOAD"])
        self.context.update_work_path(os.path.dirname(self.env["IRGEN_WORK_PATH"]))
        self.init_logger()
        self.context.check_redis_cached_config()
        self.capture_db_handler = DBObjectPool.get_db_inst_by_name("ar")
    
    def init_logger(self):
        capture_log_init(log_dir=self.context.LOG_DIR, log_mode="a", log_name="ar.log", log_level="DEBUG")
    
    def run_ar_handler(self):
        
        parser = ARParser(context=self.context, command=self.command)
        
        ar, options = parser.parse_command()
        self.ar = real_binary_path(ar)
        
        out_opt = parser.get_output_options()
        
        ar_need_record = True
        if not out_opt:
            ar_need_record = False
        
        ori_md5 = ""
        for opt in options:
            if opt.option:
                if opt.option == "-x" or opt.option == "-t":
                    # 提取文件我们不需要记录，因为最后链接还是会使用解压后的obj
                    ar_need_record = False
                elif opt.option == '-r' and ar_need_record:
                    # 将obj插入库中（替代式)
                    output_opt = parser.get_output_options()[0]
                    output_file = output_opt.parameter[0]
                    if os.path.exists(output_file):
                        ori_md5 = file_md5(output_file)
                        
        command_line = parser.get_original_command()
        
        # active_cache_env(env=self.env, context=self.context)
        ret = run_command(command=command_line, env=self.env)
        logging.debug("Record command: {}".format(" ".join(command_line)))
        
        
        self.record_command(parser=parser, ori_md5=ori_md5)
        
        return ret

    def record_command(self, parser=None, ori_md5=""):
        
        output_opt = parser.get_output_options()
        real_output = os.path.abspath(output_opt[0].parameter[0])
        
        input_options = parser.get_input_options()
        input_files = [os.path.abspath(opt.parameter[0]) for opt in input_options]
        
        command = parser.get_original_command()
        
        
        self.save_dep_info(output=real_output, command=command, input_files=input_files, ori_md5=ori_md5)
    
    
    def save_dep_info(self, output="", command=[], input_files=[], ori_md5=""):
        output_md5 = file_md5(output)
        self.capture_db_handler.set_name_dep(name_md5=output_md5, name=output)
        
        input_files_md5 = []
        for file in input_files:
            f_md5 = file_md5(file)
            if f_md5:
                input_files_md5.append(f_md5)
                self.capture_db_handler.set_name_dep(f_md5, file)
        
        self.capture_db_handler.set_cmd_dep(output_md5, [self.cwd, command])
        
        input_files_md5 = input_files_md5 + [ori_md5] if ori_md5 else input_files_md5
        self.capture_db_handler.set_link_dep(output_md5, input_files_md5)
        
    
if __name__ == "__main__":
    
    command = sys.argv[2:]      
    handler = ARHandler(command)
    
    handler.init_env()
    handler.run_ar_handler()